import time

from django.shortcuts import render,redirect,get_object_or_404
from ..models import Device,Log
import threading
from queue import Queue
from netmiko import ConnectHandler
import paramiko
from datetime import datetime
from django.utils.safestring import mark_safe
from django import forms
#导入插件
from ..utlis import pagination



"""
已实现批量登录设备执行命令；

待优化项目：
1、cisco设备未测试；容易出现风险点在 enable密码进入
2、没有配置多线程、异步等；待优化
3、log日志未添加，有问题；
4、没有添加搜索功能，当设备过多时如何处理
"""



def config(request):

    if request.method == 'GET':

        data_dict = {}

        search_data1 = request.GET.get("q1", "")
        search_data2 = request.GET.get( "q2", "")
        search_data3 = request.GET.get("q3", "")

        if search_data1:
            data_dict["ip_address__contains"] = search_data1

        if search_data2:
            data_dict["diqu__contains"] = search_data2

        if search_data3:
            data_dict["xinghao__contains"] = search_data3

        if search_data2 and search_data3:
            data_dict={
                "diqu":search_data2,
                "xinghao":search_data3 ,
            }

        # 定义当前页
        page = int(request.GET.get('page', 1))

        # 定义页码显示多少数据
        page_size = 10

        # 定义每页开始位置
        start = (page - 1) * page_size

        # 定义每页结束的位置
        end = page * page_size

        devices = Device.objects.filter(**data_dict)[start:end]

        # 总计总数据
        total_count = Device.objects.filter(**data_dict).count()

        # 计算出总页面
        total_page_count, div = divmod(total_count, page_size)
        if div:
            total_page_count += 1

        # 计算出，显示当前页的前5页和后5页
        plus = 5

        if total_page_count <= 2 * plus + 1:
            # 当数据库中数据量少时，小于11页
            start_page = 1  # 开始页=1
            end_page = total_page_count  # 结束也=当前总页码
        else:
            # 当前页码<5时
            if page <= plus:
                start_page = 1
                end_page = 2 * plus + 1
            else:
                # 当前页码 + 要显示的页码 > 总页码时
                if (page + plus) > total_page_count:
                    start_page = total_page_count - 2 * plus
                    end_page = total_page_count
                else:
                    start_page = page - plus
                    end_page = page + plus
        # 页码
        # 定义一个列表
        page_str_list = []

        # 首页
        page_str_list.append('<li><a href="?page={}">首页</a></li>'.format(1))

        # 上一页
        if page > 1:
            prev = '<li><a href="?page={}">上一页</a></li>'.format(page - 1)
        else:
            prev = '<li><a href="?page={}">上一页</a></li>'.format(1)
        page_str_list.append(prev)

        # for循环，生成开始页和结束页
        for i in range(start_page, end_page + 1):
            # 如果i=当前页，在前端加个样式，如果不等于当前页则不添加
            if i == page:
                ele = '<li class="active"><a href="?page={}">{}</a></li>'.format(i, i)
            else:
                ele = '<li><a href="?page={}">{}</a></li>'.format(i, i)
            # 将生成出来的页码写入到列表中
            page_str_list.append(ele)

        # 下一页
        if page < total_page_count:
            prev = '<li><a href="?page={}">下一页</a></li>'.format(page + 1)
        else:
            prev = '<li><a href="?page={}">下一页</a></li>'.format(total_page_count)
        page_str_list.append(prev)

        # 尾页
        page_str_list.append('<li><a href="?page={}">尾页</a></li>'.format(total_page_count))

        page_string = mark_safe("".join(page_str_list))
        return render(request,"config.html",{"devices":devices,"page_string":page_string,"search_data1":search_data1,"search_data2":search_data2,"search_data3":search_data3})

    elif request.method == 'POST':
        result = []
        selected_devices_id = request.POST.getlist('device')
        while '' in selected_devices_id:
            selected_devices_id.remove('')

        huawei_command = request.POST['huawei_command'].splitlines()

        cisco_command = request.POST['cisco_command'].splitlines()
        for x in selected_devices_id:
            try:
                dev = get_object_or_404(Device,pk=x)
                ssh_client = paramiko.SSHClient()
                ssh_client.set_missing_host_key_policy(paramiko.AutoAddPolicy())
                ssh_client.connect(hostname=dev.ip_address,username=dev.username,password=dev.password,look_for_keys=False)
                if dev.dev_name.lower() == 'cisco':
                    conn = ssh_client.invoke_shell()
                    result.append(f'{dev.ip_address}上的运行结果:')
                    conn.send('conf t \n')
                    time.sleep(1)
                    for cmd in cisco_command:
                        conn.send(cmd + ' \n')
                        time.sleep(1)
                        output = conn.recv(65535).decode('ascii')
                        result.append(output)
                elif dev.dev_name.lower() == 'huawei':
                    conn = ssh_client.invoke_shell()
                    result.append(f'{dev.ip_address}上的运行结果:')
                    conn.send('sys \n')
                    time.sleep(1)
                    for cmd in huawei_command:
                        conn.send(cmd + ' \n')
                        time.sleep(1)
                        output = conn.recv(65535).decode('ascii')
                        result.append(output + '\n\n\n\n')
                # log = Log(target=dev.ip_address, action='Configure', status='Seccess', time=datetime.now(),messages='No Error')
                # log.save()
            except Exception as e:
                # log = Log(target=dev.ip_address, action='Configure', status='Seccess', time=datetime.now(), messages=e)
                # log.save()
                print("执行失败")
        result = '\n'.join(result)
        return render(request, "verify_config.html", {'result': result})




